#include "stdafx.h"
#include "VSql.h"
				 
/**************************************
// VDictSqlSelectValues ///////////////////////////////////////////////////////

//
QMap<QString,QString>	VDictSqlSelectValues::mapDbFields() {
	QMap<QString,QString> map;
		map[VDict::nameId()]           = "n.FNameId";
		map[VDict::name()]             = "n.FName";
		map[VDict::title()]            = "n.FTitle";
		map[VDict::dateCreationName()] = "n.FCreate";

		map[VDict::linkId()]           = "l.FLinkId";
		map[VDict::parentLinkId()]     = "l.FParentLinkId";
		map[VDict::pos()]              = "l.FPos";
		map[VDict::dateCreationLink()] = "l.FCreate";
	return map;
}

//
QList<VRecord> VDictSqlSelectValues::exec(const QVariant& linkId,const VRecord& prototype) const {
	QMap<QString,QString>	dbFields = mapDbFields();
	VSqlQuery query(mDb);
	QString sql = "select  ";
	
	for (int i = 0; i < prototype.count(); i++) {
		VField* field = prototype.fieldPtr(i);
		
		if (dbFields.contains(field->name()))	{
			sql += dbFields[field->name()];
			sql += ",";

			query.addParamOut(field->name());
		}
	}
	sql.remove(sql.length()-1,1);

	sql +=
		" "
		"from      TLinks l "
		"left join TNames n on n.FNameId = l.FNameId "

		"where     l.FLinkId = :0 "
		"order by  l.FPos "
	;

	query.addParamIn(VDict::linkId());
	query.bindSql(sql);

	query.setValueIn(VDict::linkId(),linkId);
	query.exec();
	
	VSqlQuery queryHasChildren(mDb);
	int indexLinkId = -1;
	int indexHasChildren = prototype.indexOf(VDict::hasChildren());

	if (indexHasChildren >= 0) {
		indexLinkId = prototype.indexOf(VDict::linkId());
		
		queryHasChildren.addParamOut(VDict::linkId());
		queryHasChildren.addParamIn (VDict::parentLinkId());

		queryHasChildren.bindSql(
			"select FLinkId "
			"from   TLinks "
			"where  FParentLinkId = :0 "
		);
	}

	QList<VRecord> records;
	
	while (query.next()) {
		VRecord record;
			record.copyNamesFrom(prototype);
			record.setValuesFrom(query.paramsOut());
		
		if (indexHasChildren >= 0)	{
			queryHasChildren.setValueIn(
				VDict::parentLinkId(),linkId
			);
			//bool ff = 
			queryHasChildren.exec();
			record.fieldPtr(indexHasChildren)->setValue(
				queryHasChildren.next()
			);
		}
		
		records += record;
	}
	
	return records;
}
		
// VDictSqlSelectChildren /////////////////////////////////////////////////////

//
QList<VRecord> VDictSqlSelectChildren::exec(const QVariant& parentLinkId,const VRecord& prototype) {
	QMap<QString,QString>	dbFields = VDictSqlSelectValues::mapDbFields();
	VSqlQuery query(mDb);
	QString sql = "select  ";
	
	for (int i = 0; i < prototype.count(); i++) {
		VField* field = prototype.fieldPtr(i);
		
		if (dbFields.contains(field->name()))	{
			sql += dbFields[field->name()];
			sql += ",";

			query.addParamOut(field->name());
		}
	}
	sql.remove(sql.length()-1,1);

	sql +=
		" "
		"from      TLinks l "
		"left join TNames n on n.FNameId = l.FNameId "

		"where     l.FParentLinkId = :0 "
		"order by  l.FPos "
	;

	query.addParamIn(VDict::parentLinkId());
	query.bindSql(sql);

	query.setValueIn(VDict::parentLinkId(),parentLinkId);
	query.exec();
	
	VSqlQuery queryHasChildren(mDb);
	int indexLinkId = -1;
	int indexHasChildren = prototype.indexOf(VDict::hasChildren());

	if (indexHasChildren >= 0) {
		indexLinkId = prototype.indexOf(VDict::linkId());
		
		queryHasChildren.addParamOut(VDict::linkId());
		queryHasChildren.addParamIn (VDict::parentLinkId());

		queryHasChildren.bindSql(
			"select FLinkId "
			"from   TLinks "
			"where  FParentLinkId = :0 "
		);
	}

	QList<VRecord> children;

	while (query.next()) {
		VRecord childRecord;
			childRecord.copyNamesFrom(prototype);
			childRecord.setValuesFrom(query.paramsOut());
		
		if (indexHasChildren >= 0)	{
			queryHasChildren.setValueIn(
				VDict::parentLinkId(),childRecord.fieldPtr(indexLinkId)->value()
			);

			queryHasChildren.exec();
			childRecord.fieldPtr(indexHasChildren)->setValue(
				queryHasChildren.next()
			);
		}

		children.append(childRecord);
	}
	
	return children;
}

// VDictSqlSelectParents //////////////////////////////////////////////////////

//
QList<VRecord> VDictSqlSelectParents::exec(const QVariant& linkId,const VRecord& prototype) const {
	QMap<QString,QString>	dbFields = VDictSqlSelectValues::mapDbFields();
	VSqlQuery query(mDb);
	QString sql = "select  ";
	
	for (int i = 0; i < prototype.count(); i++) {
		VField* field = prototype.fieldPtr(i);
		
		if (dbFields.contains(field->name()))	{
			sql += dbFields[field->name()];
			sql += ",";

			query.addParamOut(field->name());
		}
	}
	sql.remove(sql.length()-1,1);

	sql +=
		" "
		"from PGetParentsLinkId(:FLinkId) p "
		"left join TLinks l on l.FLinkId = p.FParentLinkId "
		"left join TNames n on n.FNameId = l.FNameId"
	;

	query.addParamIn(VDict::linkId());
	//bool ok = 
	query.bindSql(sql);

	query.setValueIn(VDict::linkId(),linkId);
	query.exec();

	QList<VRecord> records;
	
	while (query.next()) {
		VRecord record;
			record.copyNamesFrom(prototype);
			record.setValuesFrom(query.paramsOut());

		VField* hasChildren = record.fieldPtr(VDict::hasChildren());
		if (hasChildren) {
			hasChildren->setValue(true);
		}

		records.append(record);
	}
	
	return records;
}

// VDictSqlUpdateValue ////////////////////////////////////////////////////////

//
void VDictSqlUpdateValue::exec(const QString& name,const VRecord& record) {
	VField* field = record.findFieldPtrByName(name);
	if (!field) {
		return;
	}
	VField* nameId = record.findFieldPtrByName(VDict::nameId());
	if (!nameId) {
		return;
	}
	
	QMap<QString,QString>	dbFields;
		dbFields[VDict::name()]  = "FName";
		dbFields[VDict::title()] = "FTitle";

	if (!dbFields.contains(name)) {
		return;
	}
	
	VSqlQuery query(mDb);

	query.addParamIn( field->name());
	query.addParamIn(nameId->name());
	 
	QString sql	=
		"update TNames "
		"set    %0 = :0 "
		"where  FNameId = :1"
	;
	query.bindSql(sql.arg(dbFields[name]));

	query.setValueIn( field->name(), field->value());
	query.setValueIn(nameId->name(),nameId->value());

	query.exec();
}
****************************************************/